package arch.chameleon.module.web.interceptor.json;

import static arch.chameleon.support.constants.WebConstants.OPERATE;
import static arch.chameleon.support.constants.WebConstants.REQ_BODY;
import static arch.chameleon.support.constants.WebConstants.REQ_HEAD;
import static arch.chameleon.support.constants.WebConstants.REQ_HEADER_X_REQUESTED_WITH;
import static arch.chameleon.support.constants.WebConstants.REQ_MESSAGE;
import static arch.chameleon.support.constants.WebConstants.REQ_TYPE_XHR;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.util.WebUtils;

import arch.chameleon.module.web.resolver.CustomParameterMethodNameResolver;
import arch.chameleon.support.util.JsonUtils;

/**
 * Json包装拦截器
 * @author caobin
 * 
 * 格式定义：
 * 
 *  提交（提交KEY:"REQ_MESSAGE"）
 * 		{
 *  		"REQ_HEAD":{
 *       		"OPERATE":"save"
 *  		},
 *   		"REQ_BODY":{
 *   			"TS_CUST_NAME":"wang_yanqin",
 *   			"TS_CUST_ADD":"FangHuaRoad"    
 *   		}
 * 		}
 * 
 * 响应--RSP_STATUS: 1-SUCCESS/0-FAILURE/-1-SESSION EXPIRED
 * 		{
 *  		"RSP_HEAD":{
 *      		"RSP_STATUS":"1",
 *      		"MSG":""
 *  		},
 *  		"RSP_BODY":{
 *  			"TS_CUST_NAME":"wang_yanqin",
 *   			"TS_CUST_ADD":"FangHuaRoad"    
 *   		}
 * 		}
 *
 */
public class JsonWrapInterceptor extends HandlerInterceptorAdapter {

	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		if(xmlHttpRequestCheck(request)){
			//JSON转Map
			Map<String, Object> mpData = JsonUtils.jsonString2Map(
								WebUtils.findParameterValue(request, REQ_MESSAGE));
			
			
			Validate.notNull(mpData, "empty request message");
			//从请求中剥离出Head和Body的内容
			Map<String, String> mpReqHeader = (Map)mpData.get(REQ_HEAD);
			Validate.notNull(mpReqHeader, "empty request header");
			//获取操作名
			String strOper = mpReqHeader.get(OPERATE);
			log.debug("OPERATE: {}", new Object[]{strOper});
			request.setAttribute(parameterMethodNameResolver.getParamName(), strOper);
			
			Map<String, Object> mpReqBody = (Map)mpData.get(REQ_BODY);
			Validate.notNull(mpReqBody, "empty request body");
			request.setAttribute(REQ_BODY, mpReqBody);
		}
		return true;
	}

	
	/**
	 * 检查异步请求
	 * @param request
	 * @return
	 */
	private boolean xmlHttpRequestCheck(HttpServletRequest request){
		return REQ_TYPE_XHR.equals(request.getHeader(REQ_HEADER_X_REQUESTED_WITH));
	}
	
	private CustomParameterMethodNameResolver parameterMethodNameResolver;
	
	public void setParameterMethodNameResolver(
			CustomParameterMethodNameResolver parameterMethodNameResolver) {
		this.parameterMethodNameResolver = parameterMethodNameResolver;
	}

	private transient Logger log = LoggerFactory.getLogger(this.getClass());	
}
